package fr.univ.lille1.android.network;

import retrofit.RestAdapter;
import retrofit.http.Field;
import retrofit.http.FormUrlEncoded;
import retrofit.http.GET;
import retrofit.http.POST;
import retrofit.http.PUT;
import retrofit.http.Path;
import fr.univ.lille1.android.domain.SessionKey;
import fr.univ.lille1.android.domain.User;

/**
 * Manager of the user resource to make CRUD requests on the server.
 * 
 * @author Gerard
 */
public class UserManager {
	/**
	 * Attribute of the UserRequest interface to send request on the server.
	 * This attribute is initialized by the library retrofit.
	 */
	private UserRequest mUserRequests;

	/**
	 * Constructor of the UserManager to initialize the attribute UserRequest.
	 * 
	 * @param restAdapter
	 *            Rest adapter of the library retrofit
	 */
	public UserManager(final RestAdapter restAdapter) {
		mUserRequests = restAdapter.create(UserRequest.class);
	}

	/**
	 * Request on the server to retrieve a user with his id.
	 * 
	 * @param id
	 *            Identifier of the user
	 * @return User object
	 */
	public User findById(final int id) {
		return mUserRequests.findById(id);
	}

	/**
	 * Request on the server to retrieve a user with his e-mail.
	 * 
	 * @param mail
	 *            Email of the user
	 * @return User object
	 */
	public User findByEmail(final String mail) {
		return mUserRequests.findByEmail(mail);
	}

	/**
	 * Request on the server to update a user of the system.
	 * 
	 * @param id
	 *            Identifier of the user
	 * @param name
	 *            Name of the user
	 * @param password
	 *            Password of the user
	 * @param mail
	 *            Email of the user
	 * @return User object
	 */
	public User update(final int id, final String name, final String password,
			final String mail) {
		return mUserRequests.update(id, name, password, mail);
	}

	/**
	 * Request on the server to create a new user on the system.
	 * 
	 * @param name
	 *            Name of the user
	 * @param password
	 *            Password of the user
	 * @param mail
	 *            Email of the user
	 * @return {@link SessionKey} object
	 */
	public SessionKey signIn(final String name, final String password,
			final String mail) {
		return mUserRequests.signIn(name, password, mail);
	}

	/**
	 * Request on the server to log in a user on the system.
	 * 
	 * @param password
	 *            Password of the user
	 * @param mail
	 *            Email of the user
	 * @return {@link SessionKey} object
	 */
	public SessionKey login(final String password, final String mail) {
		return mUserRequests.login(password, mail);
	}

	/**
	 * Request on the server to log out a user on the system.
	 * 
	 * @param mail
	 *            Email of the user
	 */
	public void logout(final String mail) {
		mUserRequests.logout(mail);
	}

	/**
	 * Interface to match some methods with API urls of the server. The server
	 * allow any clients to make CRUD request on User resource.
	 * 
	 * @author Gerard
	 */
	interface UserRequest {
		@GET("/user/{id}")
		User findById(@Path("id") int id);

		@GET("/user/{id}")
		User findByEmail(@Path("id") String email);

		@FormUrlEncoded
		@POST("/user")
		User update(@Field("id") int id, @Field("name") String name,
				@Field("password") String password, @Field("mail") String mail);

		@FormUrlEncoded
		@PUT("/user")
		SessionKey signIn(@Field("name") String name,
				@Field("password") String password, @Field("mail") String mail);

		@FormUrlEncoded
		@POST("/login")
		SessionKey login(@Field("mail") String mail,
				@Field("password") String password);

		@FormUrlEncoded
		@POST("/logout")
		void logout(@Field("mail") String mail);
	}
}
